package cn.callmee.springboot.pulsar.starter.client.config.aspect;

import cn.callmee.springboot.pulsar.starter.client.PulsarProducerTemplate;
import cn.callmee.springboot.pulsar.starter.client.annotations.PulsarProducer;
import cn.callmee.springboot.pulsar.starter.client.config.PulsarClientInitialConfiguration;
import cn.callmee.springboot.pulsar.starter.client.utils.SchemaUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

@Component
@Slf4j
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class PulsarProducerAspect {

    @Autowired
    private PulsarProducerTemplate pulsarProducerTemplate;

    @Pointcut("execution(* *..*(..)) && @annotation(cn.callmee.springboot.pulsar.starter.client.annotations.PulsarProducer)")
    public void processProducer() {
    }

    @AfterReturning(value = "processProducer()", returning = "proceedResult")
    public void produceAfterProcess(JoinPoint joinPoint, Object proceedResult) {
        if (null != proceedResult) {
            // 非空返回值则执行消息发送
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Class<?> returnType = signature.getReturnType();
            Method method = signature.getMethod();
            String name = method.getName();
            PulsarProducer annotationPulsarProducer = method.getAnnotation(PulsarProducer.class);
            String[] annotationTopicArr = SchemaUtils.generateProducerTopicList(annotationPulsarProducer);
            for (String annotationTopic : annotationTopicArr) {
                String topic = PulsarClientInitialConfiguration.STRING_VALUE_RESOLVER.resolveStringValue(StringUtils.hasText(annotationTopic) ? annotationTopic : name);
                boolean async = annotationPulsarProducer.async();
                if (async) {
                    pulsarProducerTemplate.sendAsync(topic, returnType.cast(proceedResult));
                } else {
                    pulsarProducerTemplate.send(topic, returnType.cast(proceedResult));
                }
                log.debug("send message to {}: {}", topic, proceedResult);

            }
        }
    }

    // @Around("processProducer()")
    // public Object afterProcessProducer(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    //     Object proceedResult = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
    //     // 对定义的生产者返回值进行非空判断
    //     if (null != proceedResult) {
    //         // 非空返回值则执行消息发送
    //         MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
    //         Class returnType = signature.getReturnType();
    //         Method method = signature.getMethod();
    //         String name = method.getName();
    //         PulsarProducer annotationPulsarProducer = method.getAnnotation(PulsarProducer.class);
    //         String[] annotationTopicArr = SchemaUtils.generateProducerTopicList(annotationPulsarProducer);
    //         for (String annotationTopic : annotationTopicArr) {
    //             String topic = PulsarClientInitialConfiguration.STRING_VALUE_RESOLVER.resolveStringValue(StringUtils.hasText(annotationTopic) ? annotationTopic : name);
    //             boolean async = annotationPulsarProducer.async();
    //             if (async) {
    //                 pulsarProducerTemplate.sendAsync(topic, returnType.cast(proceedResult));
    //             } else {
    //                 pulsarProducerTemplate.send(topic, returnType.cast(proceedResult));
    //             }
    //             log.debug("send message to {}: {}", topic, proceedResult);
    //
    //         }
    //     }
    //     return proceedResult;
    // }
}
